package com.vitalfit.service.serviceImpl;

import com.vitalfit.client.UserServiceClient;
import com.vitalfit.enums.FitnessPlanTypeEnum;
import com.vitalfit.enums.OrderStateEnum;
import com.vitalfit.exception.AppointmentException;
import com.vitalfit.exception.FitnessPlanException;
import com.vitalfit.exception.UserNotFoundException;
import com.vitalfit.mapper.AppointmentMapper;
import com.vitalfit.mapper.FitnessPlanMapper;
import com.vitalfit.model.dto.AppointmentDTO;
import com.vitalfit.model.dto.FitnessPlanDTO;
import com.vitalfit.model.entity.fitness.Appointment;
import com.vitalfit.model.entity.fitness.FitnessPlan;
import com.vitalfit.model.entity.user.Customer;
import com.vitalfit.model.entity.user.Trainer;
import com.vitalfit.model.vo.AppointmentVO;
import com.vitalfit.model.vo.FitnessPlanVO;
import com.vitalfit.repository.AppointmentRepository;
import com.vitalfit.repository.FitnessPlanRepository;
import com.vitalfit.service.AppointmentService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;


@Service
@RequiredArgsConstructor
public class AppointmentServiceImpl implements AppointmentService {

    private final UserServiceClient userServiceClient;

    private final FitnessPlanRepository fitnessPlanRepository;

    private final AppointmentRepository appointmentRepository;

    @Override
    @Transactional
    public AppointmentVO makeAppointment(String token, Integer userId, AppointmentDTO appointmentDTO) {
        Customer customer = userServiceClient.getCustomerById(token,userId);

        Trainer trainer = userServiceClient.getTrainerByEmail(token, appointmentDTO.getTrainerEmail());

        if (fitnessPlanRepository.findFitnessPlanByCustomerAndOrderStateEnum(OrderStateEnum.EXECUTED, customer.getId()).isEmpty()){
            throw new AppointmentException("The user must purchase fitness plan first");
        }

        if (!appointmentRepository.findOverlappingAppointments(trainer,appointmentDTO.getStartDateTime(),
                appointmentDTO.getEndDateTime()).isEmpty()) {
            throw new AppointmentException("The trainer is not available now");
        }

        if (fitnessPlanRepository.findFitnessPlanByCustomer(customer.getId()).getStarRequired() != trainer.getStarRating()){
            throw new AppointmentException("Your fitness plan can not order current trainer");
        }

        Appointment appointment = AppointmentMapper.INSTANCE.appointmentDTOToAppointment(appointmentDTO,customer,trainer);

        appointmentRepository.save(appointment);

        return AppointmentMapper.INSTANCE.appointmentToAppointmentVO(appointment,trainer);

    }


    
    @Override
    @Transactional
    public FitnessPlanVO purchaseFitnessPlan(String token, Integer userId, FitnessPlanDTO fitnessPlanDTO) {

        Customer customer = userServiceClient.getCustomerById(token,userId);
        if (!fitnessPlanRepository.findFitnessPlanByCustomerAndOrderStateEnum(OrderStateEnum.EXECUTED,customer.getId()).isEmpty()){
            throw new FitnessPlanException("The user has already had a fitness plan");
        }

        FitnessPlanTypeEnum fitnessPlanTypeEnum = FitnessPlanTypeEnum.getFitnessPlanByPlanName(fitnessPlanDTO.getPlanType());
        FitnessPlan fitnessPlan  = FitnessPlanMapper.INSTANCE.fitnessPlanDTOToFitnessPlan(fitnessPlanDTO,customer
                ,fitnessPlanTypeEnum, OrderStateEnum.EXECUTED);
        fitnessPlan.setPlanPrice(BigDecimal.valueOf(fitnessPlanTypeEnum.getPlanPrice()));
        fitnessPlanRepository.save(fitnessPlan);

        return FitnessPlanMapper.INSTANCE.fitnessPlanToFitnessPlanVO(fitnessPlan);

    }

    @Override
    @Transactional
    public Page<Appointment> getUserAppointmentList(String token, Integer userId, Integer page, Integer size) {
        // 验证用户是否有效或获取用户信息，可根据实际情况调整
        Customer customer = userServiceClient.getCustomerById(token, userId);
        if (customer == null) {
            throw new UserNotFoundException("用户不存在");
        }

        // 创建分页请求。注意PageRequest的页数是从0开始的。
        Pageable pageable = PageRequest.of(page, size);

        // 从repository中获取数据

        return appointmentRepository.findByCustomerId(userId, pageable);
    }

    @Override
    @Transactional
    public Page<Appointment> getAllAppointmentList(Integer page, Integer size) {
        // 创建分页请求
        Pageable pageable = PageRequest.of(page, size);

        // 从repository中获取所有预约数据
        return appointmentRepository.findAll(pageable);
    }



}
